/*
 * key_hal.c
 *
 *  Created on: Sep 14, 2013
 *      Author: Ken Arok
 */

#include "config_board.h"

#if BOARD_2_1_USED


#include "board.h"
#include "gpio.h"
#include "delay.h"
#include "key_hal.h"


/** \brief Tick delay.
 *
 */
static void _tick_delay(uint16_t _count) {
	uint16_t i;

	for(i = 0; i < _count; i++);
}

/** \brief Scan port of Keypad.
 *
 */
static uint8_t _port_scan(const uint8_t _logic) {
	uint8_t _pin_state;

	gpio_write_port(KEYPAD_PORT, _logic);
	gpio_write_ddr(KEYPAD_DDR, ~_logic);
	_tick_delay(10);
	_pin_state = gpio_read_pin(KEYPAD_PIN);
	_pin_state = _pin_state & 0x0F;

	return _pin_state;

}

/** \brief Scan the pressed key button.
 *
 * \return KEYWORD		16 bit keyword representative for pressed button.
 *
 */
static uint16_t _scan_button(void) {
	const uint8_t _col_val[4] = {0x7F, 0xBF, 0xDF, 0xEF};
	uint8_t _rxKeyByte, _idle_logic = 0x0F;
	uint16_t _button_val = 0x0000;
	uint16_t _dummy16;

	/* Scan column 0. */
	_rxKeyByte = _port_scan(_col_val[0]);
	_dummy16 = (uint16_t)_rxKeyByte & 0x000F;
	_dummy16 = _dummy16 << 12;
	_button_val = _button_val | _dummy16;

	/* Scan column 1. */
	_rxKeyByte = _port_scan(_col_val[1]);
	_dummy16 = (uint16_t)_rxKeyByte & 0x000F;
	_dummy16 = _dummy16 << 8;
	_button_val = _button_val | _dummy16;


	/* Scan column 2. */
	_rxKeyByte = _port_scan(_col_val[2]);
	_dummy16 = (uint16_t)_rxKeyByte & 0x000F;
	_dummy16 = _dummy16 << 4;
	_button_val = _button_val | _dummy16;

	/* Scan column 3. */
	_rxKeyByte = _port_scan(_col_val[3]);
	_dummy16 = (uint16_t)_rxKeyByte & 0x000F;
	_dummy16 = _dummy16 << 0;
	_button_val = _button_val | _dummy16;

	/* Make sure all Column key are low. */
	gpio_write_port(KEYPAD_PORT, _idle_logic);
	gpio_write_ddr(KEYPAD_DDR, ~_idle_logic);

	return _button_val;

}

/* ------------------------------------------------------------------------------------------------ */

void key_init(void)
{
	uint8_t _idle_logic = 0x0F;

	gpio_write_port(KEYPAD_PORT, _idle_logic);
	gpio_write_ddr(KEYPAD_DDR, ~_idle_logic);
}


uint16_t key_get_word(void)
{
	uint16_t _key_ver1;

	delay_ms(20);
	_key_ver1 = _scan_button();
	delay_ms(1);

	return _key_ver1;

}

char key_get_char(void)
{
	uint16_t keyword;
	char retkey;

	keyword = key_get_word();

	retkey = -1;

	switch(keyword)
	{
		case KEYWORD_NUMBER0:
			retkey = '0';
		break;

		case KEYWORD_NUMBER1:
			retkey = '1';
		break;

		case KEYWORD_NUMBER2:
			retkey = '2';
		break;

		case KEYWORD_NUMBER3:
			retkey = '3';
		break;

		case KEYWORD_NUMBER4:
			retkey = '4';
		break;

		case KEYWORD_NUMBER5:
			retkey = '5';
		break;

		case KEYWORD_NUMBER6:
			retkey = '6';
		break;

		case KEYWORD_NUMBER7:
			retkey = '7';
		break;

		case KEYWORD_NUMBER8:
			retkey = '8';
		break;

		case KEYWORD_NUMBER9:
			retkey = '9';
		break;

		case KEYWORD_ASTERIC:
			retkey = '*';
		break;

		case KEYWORD_CROSS:
			retkey = '#';
		break;

		default: break;

	}

	return retkey;
}


uint16_t key_get_combine(void)
{
	uint16_t _kCombine;

	_kCombine = key_get_word();
	/* Bounce countermeasure. */
	delay_ms(200);

	return _kCombine;
}


char key_wait_keychar(const char *_keychar)
{
	char keychar;
	uint8_t i;

	if(_keychar == NULL) return 0;

	while(1) {
		keychar = key_get_char();
		i = 0;
		do {
			if(keychar == _keychar[i]) {
				return keychar;
			}
			i++;
		}while(_keychar[i]);

	}

	return 0;
}

void key_wait_release(void)
{
	while(key_get_word() != 0xFFFF);
}



#endif /* BOARD_2_1_USED */
